package com.dyna.cp.mybatis.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dyna.core.utils.PageUtil;
import com.dyna.cp.mybatis.domain.entity.DemoEduExperience;
import com.dyna.cp.mybatis.domain.entity.DemoUser;
import com.dyna.cp.mybatis.domain.resp.DemoFriendListResp;
import com.dyna.cp.mybatis.mapper.DemoUserMapper;
import com.dyna.cp.mybatis.service.MybatisService;
import com.dyna.domain.req.PageParam;
import com.dyna.domain.resp.PageResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class MybatisServiceImpl implements MybatisService {

    private final static List<DemoUser> USER_QUEUE = new ArrayList<>();

    private final DemoUserMapper demoUserMapper;
    private final PlatformTransactionManager transactionManager;
    @Autowired
    public MybatisServiceImpl(DemoUserMapper demoUserMapper,
                          PlatformTransactionManager transactionManager
    ) {
        this.demoUserMapper = demoUserMapper;
        this.transactionManager = transactionManager;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean addUser(DemoUser demoUser) {
        demoUserMapper.addUser(demoUser);

        LambdaQueryWrapper<DemoUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DemoUser::getName, demoUser.getName());
        List<DemoUser> demoUserList = demoUserMapper.selectList(queryWrapper);
        log.info("测试在事务还未提交的时候，去查询数据是否能查到。查询到数据为:{}", JSON.toJSONString(demoUserList));
        return Boolean.TRUE;
    }

    @Override
    public Boolean batchAddUser(DemoUser demoUser) {
        USER_QUEUE.add(demoUser);
        if (USER_QUEUE.size() > 1000) {
            demoUserMapper.batchSaveUser(USER_QUEUE);
            USER_QUEUE.clear();
        }
        return Boolean.TRUE;
    }

    @Override
    public DemoUser getDetail(Integer id) {
        return demoUserMapper.selectById(id);
    }

    @Override
    public List<DemoUser> getUserByName(String name) {
        return demoUserMapper.queryUserByName(name);
    }

    @Override
    public Boolean manualTransactional() {
        // 先删再查
        demoUserMapper.deleteById(853878);
        DemoUser demoUser = demoUserMapper.selectById(853878);
        log.info("不使用事务删除后再查询用户，查询到用户为:{}", demoUser);
        // 开启手动事务先删再查
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        // 事务隔离级别
        definition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transaction = transactionManager.getTransaction(definition);
        try {
            demoUserMapper.deleteById(853885);
            DemoUser selectById = demoUserMapper.selectById(853885);
            log.info("使用事务后删除再查询用户，查询到用户为:{}", selectById);
            transactionManager.commit(transaction);
        }catch (Exception e) {
            log.error(e.getMessage(), e);
            transactionManager.rollback(transaction);
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean del(Integer id) {
        return demoUserMapper.deleteById(id)>0;
    }

    @Override
    public Boolean addEduExperience(DemoEduExperience body) {
        return demoUserMapper.saveEduExperience(body);
    }

    @Override
    public DemoFriendListResp testMybatisJoinFriend(Integer id) {
        return demoUserMapper.testMybatisJoinFriend(id);
    }

    @Override
    public PageResult<DemoFriendListResp> testMybatisJoinFriendPage() {
        PageParam pageParam = PageUtil.getPageParam();
        Page<DemoFriendListResp> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize()).doSelectPage(()->
                demoUserMapper.testMybatisJoinFriendPage2(pageParam.getPageSize(), pageParam.getPageNum())
        );
        return new PageResult<>(page.getResult(), page.getTotal());
    }

}
